{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Pima Indians Diabetes Data Set——Logistic回归\n",
    "数据说明： Pima Indians Diabetes Data Set（皮马印第安人糖尿病数据集） 根据现有的医疗信息预测5年内皮马印第安人糖尿病发作的概率。\n",
    "\n",
    "数据集共9个字段: 0列为pregnants(怀孕次数)； 1列为Plasma_glucose_concentration(口服葡萄糖耐量试验中2小时后的血浆葡萄糖浓度)； 2列为blood_pressure(舒张压,单位:mm Hg） 3列为Triceps_skin_fold_thickness(三头肌皮褶厚度,单位：mm） 4列为serum_insulin(餐后血清胰岛素,单位:mm） 5列为BMI,体重指数（体重（公斤）/ 身高（米）^2） 6列为Diabetes_pedigree_function(糖尿病家系作用) 7列为Age(年龄) 8列为Target(分类变量,0或1）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#导入必要的工具包\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>pregnants_tfidf</th>\n",
       "      <th>Plasma_glucose_concentration_tfidf</th>\n",
       "      <th>blood_pressure_tfidf</th>\n",
       "      <th>Triceps_skin_fold_thickness_tfidf</th>\n",
       "      <th>serum_insulin_tfidf</th>\n",
       "      <th>BMI_tfidf</th>\n",
       "      <th>Diabetes_pedigree_function_tfidf</th>\n",
       "      <th>Age_tfidf</th>\n",
       "      <th>Target</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.284073</td>\n",
       "      <td>0.832112</td>\n",
       "      <td>0.513770</td>\n",
       "      <td>0.496174</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.488388</td>\n",
       "      <td>0.253070</td>\n",
       "      <td>0.429647</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.070351</td>\n",
       "      <td>0.710115</td>\n",
       "      <td>0.699793</td>\n",
       "      <td>0.610876</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.574508</td>\n",
       "      <td>0.208467</td>\n",
       "      <td>0.393133</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.347874</td>\n",
       "      <td>0.944983</td>\n",
       "      <td>0.419439</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.311053</td>\n",
       "      <td>0.248922</td>\n",
       "      <td>0.238506</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.043778</td>\n",
       "      <td>0.462691</td>\n",
       "      <td>0.435473</td>\n",
       "      <td>0.301491</td>\n",
       "      <td>0.796572</td>\n",
       "      <td>0.377670</td>\n",
       "      <td>0.053179</td>\n",
       "      <td>0.146019</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.438430</td>\n",
       "      <td>0.162463</td>\n",
       "      <td>0.282418</td>\n",
       "      <td>0.876365</td>\n",
       "      <td>0.356584</td>\n",
       "      <td>0.538712</td>\n",
       "      <td>0.140135</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   pregnants_tfidf  Plasma_glucose_concentration_tfidf  blood_pressure_tfidf  \\\n",
       "0         0.284073                            0.832112              0.513770   \n",
       "1         0.070351                            0.710115              0.699793   \n",
       "2         0.347874                            0.944983              0.419439   \n",
       "3         0.043778                            0.462691              0.435473   \n",
       "4         0.000000                            0.438430              0.162463   \n",
       "\n",
       "   Triceps_skin_fold_thickness_tfidf  serum_insulin_tfidf  BMI_tfidf  \\\n",
       "0                           0.496174             0.000000   0.488388   \n",
       "1                           0.610876             0.000000   0.574508   \n",
       "2                           0.000000             0.000000   0.311053   \n",
       "3                           0.301491             0.796572   0.377670   \n",
       "4                           0.282418             0.876365   0.356584   \n",
       "\n",
       "   Diabetes_pedigree_function_tfidf  Age_tfidf  Target  \n",
       "0                          0.253070   0.429647       1  \n",
       "1                          0.208467   0.393133       0  \n",
       "2                          0.248922   0.238506       1  \n",
       "3                          0.053179   0.146019       0  \n",
       "4                          0.538712   0.140135       1  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train = pd.read_csv('FE_diabetes_tfidf.csv')\n",
    "train.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 768 entries, 0 to 767\n",
      "Data columns (total 9 columns):\n",
      "pregnants_tfidf                       768 non-null float64\n",
      "Plasma_glucose_concentration_tfidf    768 non-null float64\n",
      "blood_pressure_tfidf                  768 non-null float64\n",
      "Triceps_skin_fold_thickness_tfidf     768 non-null float64\n",
      "serum_insulin_tfidf                   768 non-null float64\n",
      "BMI_tfidf                             768 non-null float64\n",
      "Diabetes_pedigree_function_tfidf      768 non-null float64\n",
      "Age_tfidf                             768 non-null float64\n",
      "Target                                768 non-null int64\n",
      "dtypes: float64(8), int64(1)\n",
      "memory usage: 54.1 KB\n"
     ]
    }
   ],
   "source": [
    "train.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据准备"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train = train['Target']\n",
    "X_train = train.drop(['Target'], axis = 1)\n",
    "\n",
    "#保存特征名字以备后用（可视化）\n",
    "feat_names = X_train.columns"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 默认参数的Logistics Regression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "lr = LogisticRegression()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "logloss of each fold is: [0.62495789 0.59924238 0.61941142 0.61414603 0.62353727]\n",
      "cv logloss is: 0.6162589981975196\n"
     ]
    }
   ],
   "source": [
    "#交叉验证用于评估模型性能和进行参数调优（模型选择）\n",
    "#采样5折交叉验证\n",
    "from sklearn.model_selection import cross_val_score\n",
    "loss = cross_val_score(lr, X_train, y_train, cv = 5, scoring = 'neg_log_loss')\n",
    "print('logloss of each fold is:', -loss)\n",
    "print('cv logloss is:', -loss.mean())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "原始特征：0.47615970944434044\n",
    "log特征：0.581196363512364\n",
    "tfidf特征：0.6162589981975196\n",
    "越变越差？？？"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 正则化的 Logistic Regression及参数调优\n",
    "logistic回归的需要调整超参数有：C（正则系数，一般在log域（取log后的值）均匀设置候选参数）和正则函数penalty（L2/L1） 目标函数为：J = C sum(logloss(f(xi), yi)) + penalty"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=5, error_score='raise',\n",
       "       estimator=LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
       "          intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,\n",
       "          penalty='l2', random_state=None, solver='liblinear', tol=0.0001,\n",
       "          verbose=0, warm_start=False),\n",
       "       fit_params=None, iid=True, n_jobs=4,\n",
       "       param_grid={'penalty': ['l1', 'l2'], 'C': [0.1, 1, 10, 100, 1000]},\n",
       "       pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',\n",
       "       scoring='neg_log_loss', verbose=0)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#导入模块\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "#设置参数搜索范围\n",
    "penaltys = ['l1', 'l2']\n",
    "Cs = [0.1, 1, 10, 100, 1000]\n",
    "tuned_parameters = dict(penalty = penaltys, C = Cs)\n",
    "\n",
    "#生成学习器实例\n",
    "lr_penalty = LogisticRegression(solver = 'liblinear')\n",
    "\n",
    "#生成GridSearchCV的实例\n",
    "grid = GridSearchCV(lr_penalty, tuned_parameters, cv = 5, scoring = 'neg_log_loss', n_jobs = 4)\n",
    "\n",
    "#调用GridSearchCV的fit方法\n",
    "grid.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.616252272535896\n",
      "{'C': 1, 'penalty': 'l2'}\n"
     ]
    }
   ],
   "source": [
    "# examine the best model\n",
    "print(-grid.best_score_)\n",
    "print(grid.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "d:\\Anaconda3\\lib\\site-packages\\sklearn\\utils\\deprecation.py:122: FutureWarning: You are accessing a training score ('mean_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n",
      "d:\\Anaconda3\\lib\\site-packages\\sklearn\\utils\\deprecation.py:122: FutureWarning: You are accessing a training score ('std_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0xacc6da0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot CV误差曲线\n",
    "test_means = grid.cv_results_['mean_test_score']\n",
    "test_stds = grid.cv_results_['std_test_score']\n",
    "train_means = grid.cv_results_['mean_train_score']\n",
    "train_stds = grid.cv_results_['std_train_score']\n",
    "\n",
    "# plot results\n",
    "n_Cs = len(Cs)\n",
    "number_penaltys = len(penaltys)\n",
    "test_scores = np.array(test_means).reshape(n_Cs, number_penaltys)\n",
    "train_scores = np.array(train_means).reshape(n_Cs, number_penaltys)\n",
    "test_stds = np.array(test_stds).reshape(n_Cs, number_penaltys)\n",
    "train_stds = np.array(train_stds).reshape(n_Cs, number_penaltys)\n",
    "\n",
    "x_axis = np.log10(Cs)\n",
    "for i, value in enumerate(penaltys):\n",
    "    plt.errorbar(x_axis, -test_scores[:,i], yerr = test_stds[:,i], label = penaltys[i] + 'Test')\n",
    "    plt.errorbar(x_axis, -train_scores[:,i], yerr = train_stds[:,i], label = penaltys[i] + 'Train')\n",
    "    \n",
    "plt.legend()\n",
    "plt.xlabel('log(C)')\n",
    "plt.ylabel('logloss')\n",
    "plt.savefig('LogisticGridSearchCV_C.png')\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 保存模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pickle\n",
    "pickle.dump(grid.best_estimator_, open('Diabetes_L1_org.pkl', 'wb'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
